package org.frog.sgs.card.general;

import java.util.HashMap;
import java.util.Map;

import org.frog.sgs.card.AbstractCard;
import org.frog.sgs.card.basic.Basic;
import org.frog.sgs.card.general.camp.Camp;
import org.frog.sgs.card.general.listener.all.BaseEventListener;
import org.frog.sgs.card.general.sex.Sex;
import org.frog.sgs.card.scheme.base.WuXieKeJi;
import org.frog.sgs.card.scheme.type.JudgeType;
import org.frog.sgs.event.SgsEvent;
import org.frog.sgs.event.SgsEventCode;
import org.frog.sgs.io.SgsMsg;
import org.frog.sgs.server.msg.ServerMsgWuXieKeJiAsk;

/**
 * @author duanxiangqi
 * @date 2012-10-19
 */
public abstract class AbstractGeneral extends AbstractCard implements General, BaseEventListener {

	private static final long serialVersionUID = -5756532390897353147L;

	private Camp camp;

	private Sex sex;

	private int maxStrength;

	private Map<Object, Object> attributes = new HashMap<Object, Object>();

	/**
	 * 主动添加并触发触发某个事件
	 * 
	 * @param msgCode
	 */
	public void triggerEvent(int msgCode) {
		addEventToManager(new SgsEvent(getCharacter(), msgCode));
		GeneralEventDispatcher.instance.dispatch(this, new SgsMsg(msgCode));
	}

	/**
	 * 主动添加并触发某个事件
	 * 
	 * @param msgCode
	 */
	public void triggerEvent(SgsEvent event) {
		addEventToManager(event);
		GeneralEventDispatcher.instance.dispatch(this, new SgsMsg(event.getCode()));
	}

	public void addEventToManager(SgsEvent event) {
		getCharacter().getInstance().getEventManager().addEvent(event);
	}

	public SgsEvent getLastEventFromManager() {
		return getCharacter().getInstance().getEventManager().getLast();
	}

	public void doLastEvent() {
		SgsEvent event = getLastEventFromManager();
		GeneralEventDispatcher.instance.dispatch(this, new SgsMsg(event.getCode()));
	}

	/**
	 * 删除上一个事件
	 */
	public void removeLastEventFromManager() {
		getCharacter().getInstance().getEventManager().removeLast();
	}

	/** 回合开始前初始化 */
	public void myRoundInit(SgsMsg msg) throws Exception {
		// 回合开始
		getCharacter().broadcast("回合开始");
		// 同步玩家信息到客户端
		getCharacter().syncCharacterInfo();
		// 清楚回合内临时信息
		attributes.clear();
		// 进入回合开始阶段
		removeLastEventFromManager();
		triggerEvent(SgsEventCode.MY_ROUND_START);
	}

	/** 回合开始阶段 */
	public void myRoundStart(SgsMsg msg) throws Exception {
		// 默认直接进入判定阶段
		removeLastEventFromManager();
		triggerEvent(SgsEventCode.MY_JUDGE_START);
	}

	/** 判定阶段 */
	public void myJudgeStart(SgsMsg msg) throws Exception {
		// TODO delete
		getCharacter().addJudge(JudgeType.leBuSiShu, getCharacter().getInstance().getCardManager().getOutOneBasic());
		getCharacter().addJudge(JudgeType.shanDian, getCharacter().getInstance().getCardManager().getOutOneBasic());
		Basic wxkj = getCharacter().getInstance().getCardManager().getOutBasicByType(WuXieKeJi.class);
		getCharacter().getCardsInHand().put(wxkj.getId(), wxkj);
		getCharacter().syncCharacterInfo();
		// TODO
		removeLastEventFromManager();
		// 判断是否有判定牌
		if (getCharacter().hasJudgeCard()) {
			// 如果有，则进行循环判定
			getCharacter().broadcast("判定阶段");
			triggerEvent(SgsEventCode.JUDGE_SCHEME);
		} else {
			// 如果没有 进入摸牌阶段
			triggerEvent(SgsEventCode.MY_GET_CARDS_START);
		}
	}

	/** 判定是否生效 */
	public void judgeScheme(SgsMsg msg) throws Exception {
		removeLastEventFromManager();
		JudgeType judgeType = getCharacter().getNextJudgeType();
		if (judgeType == null) {
			//没有判定或已经判定完毕
			removeLastEventFromManager();
			triggerEvent(SgsEventCode.MY_GET_CARDS_START);
		}
		//判断所有玩家的手牌中是否有【无懈可击】
		if (getCharacter().getInstance().hasWuXieKeJiInHands()) {
			// 如果有，从当前玩家开始顺序询问是否为我的【乐不思蜀】、【闪电】打出【无懈可击】，并为询问事件添加下一个要执行的事件为{judgeSchemeResult}
			Basic judge = getCharacter().getNextJudge();
			SgsEvent beiScheme = new SgsEvent(getCharacter(), SgsEventCode.BEI_SCHEME);
			beiScheme.setAttribute("scheme.src", this);//锦囊作用来源 当前武将
			beiScheme.setAttribute("scheme.type", judgeType);//锦囊类型
			beiScheme.setAttribute("scheme.card", judge);//锦囊牌 不一定是乐不思蜀或闪电牌，也可能是通过技能使用的其他牌
			addEventToManager(beiScheme);
			//询问完成之后查看【无懈可击】的结果
			addEventToManager(new SgsEvent(getCharacter(), SgsEventCode.JUDGE_SCHEME_RESULT));
			doLastEvent();
		} else {
			// 如果没有，执行事件{judgeSchemeGetJudge}
			triggerEvent(SgsEventCode.JUDGE_SCHEME_GET_JUDGE);
		}
	}

	/** 得到判定结果 */
	public void judgeSchemeGetJudge(SgsMsg msg) throws Exception {
	// 根据事件属性判定是否需要再获取判定牌，如果不需要继续下一个判定
	// 获取一张判定牌，生成结果
	}

	/** 获取判定牌 */
	public void judgeSchemeResult(SgsMsg msg) throws Exception {
	// 判定是否生效 如果生效执行结果 反之 继续下一个判定
	}

	/** 执行判定结果 */
	public void judgeSchemeExecute(SgsMsg msg) throws Exception {
	// 执行判定结果 继续下一个判定
	}

	/** 摸牌阶段 */
	public void myGetCardsStart(SgsMsg msg) throws Exception {
		getCharacter().broadcast("摸牌阶段");
		System.out.println("AbstractGeneral.myGetCardsStart()");
	}

	/** 从牌堆摸牌 */
	public void getCards(SgsMsg msg) throws Exception {}

	/** 出牌阶段 */
	public void myUseCardsStart(SgsMsg msg) throws Exception {}

	public void useCardsPrepare(SgsMsg msg) throws Exception {}

	public void useCards(SgsMsg msg) throws Exception {}

	public void useSha(SgsMsg msg) throws Exception {}

	public void beiSha(SgsMsg msg) throws Exception {}

	public void beiShaShanAsk(SgsMsg msg) throws Exception {}

	public void beiShaShanResult(SgsMsg msg) throws Exception {}

	public void useShaResult(SgsMsg msg) throws Exception {}

	public void useTao(SgsMsg msg) throws Exception {}

	public void useScheme(SgsMsg msg) throws Exception {}

	public void reduceStrength(SgsMsg msg) throws Exception {}

	public void addStrength(SgsMsg msg) throws Exception {}

	public void closeToDie(SgsMsg msg) throws Exception {}

	public void closeToDieAsk(SgsMsg msg) throws Exception {}

	public void die(SgsMsg msg) throws Exception {}

	public void baGuaDunAsk(SgsMsg msg) throws Exception {}

	public void baGuaDunResult(SgsMsg msg) throws Exception {}

	public void qiLinGong(SgsMsg msg) throws Exception {}

	public void fangTianHuaJi(SgsMsg msg) throws Exception {}

	public void zhangBaSheMao(SgsMsg msg) throws Exception {}

	public void qingLongYanYueDao(SgsMsg msg) throws Exception {}

	public void guanShiFu(SgsMsg msg) throws Exception {}

	public void hanBingJianAsk(SgsMsg msg) throws Exception {}

	public void hanBingJianResult(SgsMsg msg) throws Exception {}

	public void ciXiongShuangGuJianAsk(SgsMsg msg) throws Exception {}

	public void ciXiongShuangGuJianResult(SgsMsg msg) throws Exception {}

	public void beiScheme(SgsMsg msg) throws Exception {
		//		"scheme.src", this);//锦囊作用来源 当前武将
		//		"scheme.type", judgeType);//锦囊类型
		//		"scheme.card", judge);//锦囊牌 不一定是乐不思蜀或闪电牌，也可能是通过技能使用的其他牌
		SgsEvent event = getLastEventFromManager();
		System.out.println(getCharacter() + "：beiScheme" + event);
		//询问客户端是否使用【无懈可击】
		General target = (General) event.getAttributes().get("scheme.src");
		JudgeType type = (JudgeType) event.getAttributes().get("scheme.type");
		getCharacter().sendMsg(new ServerMsgWuXieKeJiAsk(target.getCharacter().getViewName(), type.getName()));
		event.setCode(SgsEventCode.WU_XIE_KE_JI_RESULT);
	}

	/** 询问是否使用【无懈可击】 */
	public void wuXieKeJiAsk(SgsMsg msg) throws Exception {
		int id = msg.readInt();
		SgsEvent event = getLastEventFromManager();

		if (id == 0) {
			//不使用
			event.setAttribute("", false);
			//下一个
		} else {
			//使用
		}

	}

	public void wuXieKeJiResult(SgsMsg msg) throws Exception {}

	public void shanDian(SgsMsg msg) throws Exception {}

	public void leBuSiShu(SgsMsg msg) throws Exception {}

	public void jieDaoShaRen(SgsMsg msg) throws Exception {}

	public void beiJieDaoShaRen(SgsMsg msg) throws Exception {}

	public void wuGuFengDeng(SgsMsg msg) throws Exception {}

	public void wuGuFengDengExecute(SgsMsg msg) throws Exception {}

	public void wuZhongShengYou(SgsMsg msg) throws Exception {}

	public void wuZhongShengYouExecute(SgsMsg msg) throws Exception {}

	public void taoYuanJieYi(SgsMsg msg) throws Exception {}

	public void taoYuanJieYiExecute(SgsMsg msg) throws Exception {}

	public void nanManRuQin(SgsMsg msg) throws Exception {}

	public void nanManRuQinNeedShaAsk(SgsMsg msg) throws Exception {}

	public void nanManRuQinNeedShaResult(SgsMsg msg) throws Exception {}

	public void wanJianQiFa(SgsMsg msg) throws Exception {}

	public void wanJianQiFaNeedShanAsk(SgsMsg msg) throws Exception {}

	public void wanJianQiFaNeedShanResult(SgsMsg msg) throws Exception {}

	public void shunShouQianYang(SgsMsg msg) throws Exception {}

	public void shunShouQianYangExecute(SgsMsg msg) throws Exception {}

	public void guoHeChaiQiao(SgsMsg msg) throws Exception {}

	public void guoHeChaiQiaoAsk(SgsMsg msg) throws Exception {}

	public void guoHeChaiQiaoExecute(SgsMsg msg) throws Exception {}

	public void jueDou(SgsMsg msg) throws Exception {}

	public void jueDouExecute(SgsMsg msg) throws Exception {}

	public void jueDouNeedShaAsk(SgsMsg msg) throws Exception {}

	public void jueDouNeedShaResult(SgsMsg msg) throws Exception {}

	public void myGiveupCardsStart(SgsMsg msg) throws Exception {}

	public void giveupCardsAsk(SgsMsg msg) throws Exception {}

	public void giveupCardsExecute(SgsMsg msg) throws Exception {}

	public void myRoundEnd(SgsMsg msg) throws Exception {}

	public void roundEndExecute(SgsMsg msg) throws Exception {}

	public Camp getCamp() {
		return camp;
	}

	public void setCamp(Camp camp) {
		this.camp = camp;
	}

	public int getMaxStrength() {
		return maxStrength;
	}

	public void setMaxStrength(int maxStrength) {
		this.maxStrength = maxStrength;
	}

	public void setAttribute(Object key, Object value) {
		attributes.put(key, value);
	}

	public Object getAttribute(Object key) {
		return attributes.get(key);
	}

	public boolean hasAttribute(Object key) {
		return attributes.containsKey(key);
	}

	public void removeAttribute(Object key) {
		attributes.remove(key);
	}

	public Map<Object, Object> getAttributes() {
		return attributes;
	}

	public void setAttributes(Map<Object, Object> attributes) {
		this.attributes = attributes;
	}

	public Sex getSex() {
		return sex;
	}

	public void setSex(Sex sex) {
		this.sex = sex;
	}

}
